package com.romadan.utils;

import java.util.ArrayList;
import java.util.List;

import com.romadan.core.linearanalys.logic.SParameters;
import com.romadan.core.linearanalys.logic.YParameters;
import com.romadan.core.linearanalys.logic.ZParameters;
import com.romadan.utils.math.Complex;

public class Conversions {

	// Constants
	private static final Complex Z01 = new Complex(50, 0);
	private static final Complex Z02 = new Complex(50, 0);
	private static final Complex ONE = new Complex(1, 0);
	private static final Complex TWO = new Complex(2, 0);

	// Function for conversion from S-parameters to Z-parameters
	public static List<ZParameters> conversion_SZ(List<SParameters> sParameters) {
		List<ZParameters> zParameters = new ArrayList<ZParameters>();

		for (SParameters s : sParameters) {
			ZParameters z = new ZParameters();
			Complex znam = (ONE.minus(s.getS11())).mul(ONE.minus(s.getS22())).minus(
					s.getS12().mul(s.getS21()));
			Complex z11 = (ONE.minus(s.getS22()))
					.mul(Z01.conj().plus(s.getS11().mul(Z01)))
					.plus(s.getS12().mul(s.getS21()).mul(Z01)).div(znam);
			Complex z12 = (TWO.mul(s.getS12())).mul(
					new Complex(Math.pow(Z01.real() * Z02.real(), 0.5), 0))
					.div(znam);
			Complex z21 = (TWO.mul(s.getS21())).mul(
					new Complex(Math.pow(Z01.real() * Z02.real(), 0.5), 0))
					.div(znam);
			Complex z22 = (ONE.minus(s.getS11()))
					.mul(Z02.conj().plus(s.getS22().mul(Z02)))
					.plus(s.getS12().mul(s.getS21()).mul(Z02)).div(znam);
			
			z.setZ11(z11);
			z.setZ12(z12);
			z.setZ21(z21);
			z.setZ22(z22);
			z.setFrequency(s.getFrequency());
			
			zParameters.add(z);
		}

		return zParameters;
	}

	// Function for conversion from S-parameters to Y-parameters
	public static List<YParameters> conversion_SY(List<SParameters> sParameters) {
		List<YParameters> yParameters = new ArrayList<YParameters>();

		for (SParameters s : sParameters) {
			Complex znam = (Z01.conj().plus(s.getS11().mul(Z01)).mul(Z02.conj()
					.plus(s.getS22().mul(Z02)))).minus(s.getS12().mul(s.getS21())
					.mul(Z01).mul(Z02));
			Complex y11 = (ONE.minus(s.getS11())
					.mul(Z02.conj().plus(s.getS22().mul(Z02)))).plus(
					s.getS12().mul(s.getS21()).mul(Z02)).div(znam);
			Complex y12 = s.getS12().mul(-2)
					.mul(Math.pow(Z01.real() * Z02.real(), 0.5)).div(znam);
			Complex y21 = s.getS21().mul(-2)
					.mul(Math.pow(Z01.real() * Z02.real(), 0.5)).div(znam);
			Complex y22 = (ONE.minus(s.getS22())
					.mul(Z01.conj().plus(s.getS11().mul(Z01)))).plus(
					s.getS12().mul(s.getS21()).mul(Z01)).div(znam);
			
			YParameters y = new YParameters();
			y.setY11(y11);
			y.setY12(y12);
			y.setY21(y21);
			y.setY22(y22);
			y.setFrequency(s.getFrequency());
			
			yParameters.add(y);
		}

		return yParameters;
	}

	// Function for conversion from Z-parameters to Y-parameters
	public static List<YParameters> conversion_ZY(List<ZParameters> zParameters) {
		List<YParameters> yParameters = new ArrayList<YParameters>();

		for (ZParameters z : zParameters) {
			Complex znam = z.getZ11().mul(z.getZ22()).minus(z.getZ12().mul(z.getZ21()));
			Complex y11 = z.getZ22().div(znam);
			Complex y12 = z.getZ12().mul(-1).div(znam);
			Complex y21 = z.getZ21().mul(-1).div(znam);
			Complex y22 = z.getZ11().div(znam);
			
			YParameters y = new YParameters();
			y.setY11(y11);
			y.setY12(y12);
			y.setY21(y21);
			y.setY22(y22);
			y.setFrequency(z.getFrequency());
			
			yParameters.add(y);
		}

		return yParameters;
	}
	
	// Function for conversion from Y-parameters to Z-parameters
		public static List<ZParameters> conversion_YZ(List<YParameters> yParameters) {
			List<ZParameters> zParameters = new ArrayList<ZParameters>();

			for (YParameters y : yParameters) {
				Complex znam = y.getY11().mul(y.getY22()).minus(y.getY12().mul(y.getY21()));
				Complex z11 = y.getY22().div(znam);
				Complex z12 = y.getY12().mul(-1).div(znam);
				Complex z21 = y.getY21().mul(-1).div(znam);
				Complex z22 = y.getY11().div(znam);
				
				ZParameters z = new ZParameters();
				z.setZ11(z11);
				z.setZ12(z12);
				z.setZ21(z21);
				z.setZ22(z22);
				z.setFrequency(y.getFrequency());
				
				zParameters.add(z);
			}

			return zParameters;
		}
}
